package aceim.protocol.snuk182.icq.inner.dataprocessing;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import aceim.protocol.snuk182.icq.inner.ICQConstants;
import aceim.protocol.snuk182.icq.inner.ICQServiceInternal;
import aceim.protocol.snuk182.icq.inner.ICQServiceResponse;
import aceim.protocol.snuk182.icq.inner.dataentity.Flap;
import aceim.protocol.snuk182.icq.inner.dataentity.ICQBuddy;
import aceim.protocol.snuk182.icq.inner.dataentity.ICQBuddyGroup;
import aceim.protocol.snuk182.icq.inner.dataentity.ICQIconData;
import aceim.protocol.snuk182.icq.inner.dataentity.ICQOnlineInfo;
import aceim.protocol.snuk182.icq.inner.dataentity.Snac;
import aceim.protocol.snuk182.icq.inner.dataentity.TLV;
import aceim.protocol.snuk182.icq.utils.MD5;
import aceim.protocol.snuk182.icq.utils.ProtocolUtils;
public class SSIProcessor {
byte[] newIcon = null;
private ICQServiceInternal service;
private ICQBuddyGroup tmpGroup;
private ICQBuddy tmpBuddy;
// private boolean authRequired = false;
private static final byte ACTION_NONE = 0;
private static final byte ACTION_ADD_BUDDY = 1;
private static final byte ACTION_DELETE_BUDDY = 2;
private static final byte ACTION_ADD_GROUP = 3;
private static final byte ACTION_DELETE_GROUP = 4;
private static final byte ACTION_RENAME_BUDDY = 5;
private static final byte ACTION_RENAME_GROUP = 6;
private static final byte ACTION_MOVE_BUDDY = 7;
//private static final byte ACTION_UPLOAD_ICON = 8;;
private byte currentAction = 0;
public SSIProcessor(ICQServiceInternal icqServiceInternal) {
this.service = icqServiceInternal;
}
public void modifyGroup(ICQBuddyGroup group) {
currentAction = ACTION_RENAME_GROUP;
tmpGroup = group;
service.getRunnableService().sendToSocket(getModifyGroupFlap(group));
}
public void addGroup(ICQBuddyGroup group) {
ICQBuddyGroup masterGroup = new ICQBuddyGroup();
masterGroup.name = "";
masterGroup.groupId = 0;
masterGroup.buddies.addAll(service.getBuddyList().getBuddyGroupIds());
masterGroup.buddies.add(group.groupId);
currentAction = ACTION_ADD_GROUP;
tmpGroup = group;
service.getRunnableService().sendMultipleToSocket(new Flap[] { getSSIEditStartFlap(), getAddGroupFlap(group), getModifyGroupFlap(masterGroup), getSSIEditEndFlap() });
}
public void moveBuddy(ICQBuddy buddy, ICQBuddyGroup oldGroup, ICQBuddyGroup newGroup) {
currentAction = ACTION_MOVE_BUDDY;
service.getRunnableService().sendMultipleToSocket(new Flap[] { getSSIEditStartFlap(), getDeleteBuddyFlap(buddy, false), getModifyGroupFlap(oldGroup) });
buddy.groupId = newGroup.groupId;
tmpBuddy = buddy;
service.getRunnableService().sendMultipleToSocket(new Flap[] { getAddBuddyFlap(buddy, newGroup, buddy.visibility == ICQConstants.VIS_NOT_AUTHORIZED, false), getModifyGroupFlap(newGroup), getSSIEditEndFlap() });
}
public void modifyBuddy(ICQBuddy buddy) {
currentAction = ACTION_RENAME_BUDDY;
tmpBuddy = buddy;
service.getRunnableService().sendToSocket(getModifyBuddyFlap(buddy, null));
}
private Flap getAddGroupFlap(ICQBuddyGroup group) {
Flap flap2 = new Flap();
flap2.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac data2 = new Snac();
data2.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data2.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMADD;
data2.requestId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMADD;
byte[] nameBytes;
try {
nameBytes = group.name.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
nameBytes = group.name.getBytes();
}
byte[] header = new byte[10 + nameBytes.length];
int pos = 0;
System.arraycopy(ProtocolUtils.short2ByteBE((short) nameBytes.length), 0, header, pos, 2);
pos += 2;
System.arraycopy(nameBytes, 0, header, pos, nameBytes.length);
pos += nameBytes.length;
System.arraycopy(ProtocolUtils.short2ByteBE((short) group.groupId), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 1), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0), 0, header, pos, 2);
pos += 2;
data2.plainData = header;
flap2.data = data2;
return flap2;
}
private Flap getModifyBuddyFlap(ICQBuddy buddy, ICQOnlineInfo info) {
if (buddy == null && info == null){
return null;
}
Flap flap2 = new Flap();
flap2.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac data2 = new Snac();
data2.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data2.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_GROUPHEADERUPD;
data2.requestId = ICQConstants.SNAC_SERVERSIDEINFO_GROUPHEADERUPD;
byte[] uinBytes;
if (buddy != null){
try {
uinBytes = buddy.uin.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
uinBytes = buddy.uin.getBytes();
}
} else {
uinBytes = new byte[0];
}
byte[] header = new byte[10 + uinBytes.length];
int pos = 0;
System.arraycopy(ProtocolUtils.short2ByteBE((short) uinBytes.length), 0, header, pos, 2);
pos += 2;
System.arraycopy(uinBytes, 0, header, pos, uinBytes.length);
pos += uinBytes.length;
System.arraycopy(ProtocolUtils.short2ByteBE((short) (buddy != null ? buddy.groupId : 0)), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) (buddy != null ? buddy.itemId : info.itemId)), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) (buddy != null ? 0 : 4)), 0, header, pos, 2);
pos += 2;
if (buddy != null){
String screenname;
if (buddy.screenName != null) {
screenname = buddy.screenName;
} else {
screenname = buddy.uin;
}
TLV tlv = new TLV();
tlv.type = 0x131;
byte[] screennameBytes;
try {
screennameBytes = screenname.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
screennameBytes = screenname.getBytes();
}
tlv.value = screennameBytes;
TLV email = new TLV();
email.type = 0x137;
TLV sms = new TLV();
sms.type = 0x13a;
TLV comment = new TLV();
comment.type = 0x13c;
if (buddy.visibility == ICQConstants.VIS_NOT_AUTHORIZED) {
TLV authTlv = new TLV();
authTlv.type = 0x66;
data2.data = new TLV[] { tlv, sms, email, comment, authTlv };
} else {
data2.data = new TLV[] { tlv, sms, email, comment };
}
System.arraycopy(ProtocolUtils.short2ByteBE((short) (16 + screennameBytes.length + (buddy.visibility == ICQConstants.VIS_NOT_AUTHORIZED ? 4 : 0))), 0, header, pos, 2);
pos += 2;
} else {
TLV visTlv = new TLV();
visTlv.type = 0xca;
visTlv.value = new byte[]{info.visibility};
TLV permTlv = new TLV();
permTlv.type = 0xcb;
permTlv.value = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
TLV xz1 = new TLV();
xz1.type = 0xd0;
xz1.value = new byte[]{1};
TLV xz2 = new TLV();
xz2.type = 0xd1;
xz2.value = new byte[]{1};
TLV xz3 = new TLV();
xz3.type = 0xd2;
xz3.value = new byte[]{1};
TLV xz4 = new TLV();
xz4.type = 0xd3;
xz4.value = new byte[]{1};
data2.data = new TLV[] {visTlv, permTlv, xz1, xz2, xz3, xz4};
System.arraycopy(ProtocolUtils.short2ByteBE((short) 33), 0, header, pos, 2);
pos += 2;
}
data2.plainData = header;
flap2.data = data2;
return flap2;
}
private Flap getDeleteBuddyFlap(ICQBuddy buddy, boolean fixPermissions) {
Flap flap2 = new Flap();
flap2.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac data2 = new Snac();
data2.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data2.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMREMOVE;
data2.requestId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMREMOVE;
byte[] uinBytes;
try {
uinBytes = buddy.uin.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
uinBytes = buddy.uin.getBytes();
}
byte[] header = new byte[10 + uinBytes.length];
int pos = 0;
System.arraycopy(ProtocolUtils.short2ByteBE((short) uinBytes.length), 0, header, pos, 2);
pos += 2;
System.arraycopy(uinBytes, 0, header, pos, uinBytes.length);
pos += uinBytes.length;
int groupId;
if (!fixPermissions){
groupId = buddy.groupId;
} else {
groupId = 0;
}
System.arraycopy(ProtocolUtils.short2ByteBE((short) groupId), 0, header, pos, 2);
pos += 2;
int itemId;
if (!fixPermissions){
itemId = buddy.itemId;
} else {
try {
ICQOnlineInfo nfo = service.getBuddyList().getByUin(buddy.uin);
switch (nfo.visibility) {
case ICQConstants.VIS_DENIED:
itemId = service.getBuddyList().denyList.remove(buddy.uin);
break;
case ICQConstants.VIS_PERMITTED:
itemId = service.getBuddyList().permitList.remove(buddy.uin);
break;
default:
return null;
}
} catch (Exception e) {
return null;
}
}
System.arraycopy(ProtocolUtils.short2ByteBE((short) itemId), 0, header, pos, 2);
pos += 2;
if (!fixPermissions) {
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0), 0, header, pos, 2);
} else {
ICQOnlineInfo nfo = service.getBuddyList().getByUin(buddy.uin);
switch (nfo.visibility) {
case ICQConstants.VIS_DENIED:
System.arraycopy(ProtocolUtils.short2ByteBE((short) 3), 0, header, pos, 2);
break;
case ICQConstants.VIS_PERMITTED:
System.arraycopy(ProtocolUtils.short2ByteBE((short) 2), 0, header, pos, 2);
break;
default:
return null;
}
}
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0), 0, header, pos, 2);
pos += 2;
data2.plainData = header;
flap2.data = data2;
return flap2;
}
public void removeBuddyFromContactList(ICQBuddy buddy) {
/*
* Flap flap1 = new Flap(); flap1.channel =
* ICQConstants.FLAP_CHANNELL_DATA; flap1.sequenceNumber =
* service.getFlapSeqNumber();
*
* Snac data1 = new Snac(); data1.serviceId =
* ICQConstants.SNAC_FAMILY_SERVERSIDEINFO; data1.subtypeId =
* ICQConstants.SNAC_SERVERSIDEINFO_CONTACTSEDITSTART; data1.requestId =
* ICQConstants.SNAC_SERVERSIDEINFO_CONTACTSEDITSTART;
*
* flap1.data = data1;
*/
/*
* Flap flap3 = new Flap(); flap3.channel =
* ICQConstants.FLAP_CHANNELL_DATA; flap3.sequenceNumber =
* service.getFlapSeqNumber();
*
* Snac data3 = new Snac(); data3.serviceId =
* ICQConstants.SNAC_FAMILY_SERVERSIDEINFO; data3.subtypeId =
* ICQConstants.SNAC_SERVERSIDEINFO_CONTACTSEDITEND; data3.requestId =
* ICQConstants.SNAC_SERVERSIDEINFO_CONTACTSEDITEND;
*
* flap3.data = data3;
*/
currentAction = ACTION_DELETE_BUDDY;
tmpBuddy = buddy;
service.getRunnableService().sendMultipleToSocket(new Flap[] { getSSIEditStartFlap(), getDeleteBuddyFlap(buddy, false), getSSIEditEndFlap() });
}
public void removeGroup(ICQBuddyGroup group) {
currentAction = ACTION_DELETE_GROUP;
tmpGroup = group;
service.getRunnableService().sendToSocket(getDeleteGroupFlap(group));
}
private Flap getDeleteGroupFlap(ICQBuddyGroup group) {
Flap flap2 = new Flap();
flap2.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac data2 = new Snac();
data2.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data2.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMREMOVE;
data2.requestId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMREMOVE;
byte[] nameBytes;
try {
nameBytes = group.name.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
nameBytes = group.name.getBytes();
}
byte[] header = new byte[10 + nameBytes.length];
int pos = 0;
System.arraycopy(ProtocolUtils.short2ByteBE((short) nameBytes.length), 0, header, pos, 2);
pos += 2;
System.arraycopy(nameBytes, 0, header, pos, nameBytes.length);
pos += nameBytes.length;
System.arraycopy(ProtocolUtils.short2ByteBE((short) group.groupId), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 1), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0), 0, header, pos, 2);
pos += 2;
data2.plainData = header;
flap2.data = data2;
return flap2;
}
public void parseAuthRequest(byte[] plainData) {
if (plainData == null || plainData.length < 2) {
return;
}
byte uinLength = plainData[0];
byte[] uinBytes = new byte[uinLength];
System.arraycopy(plainData, 1, uinBytes, 0, uinLength);
String uin = new String(uinBytes);
int reasonLength = ProtocolUtils.unsignedShort2Int(ProtocolUtils.bytes2ShortBE(plainData, 1 + uinLength));
byte[] reasonBytes = new byte[reasonLength];
System.arraycopy(plainData, 3 + uinLength, reasonBytes, 0, reasonLength);
String reason;
try {
reason = new String(reasonBytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
reason = new String(reasonBytes);
}
service.getServiceResponse().respond(ICQServiceResponse.RES_AUTHREQUEST, uin, reason);
}
public void parseSSIResponse(byte[] plainData) {
if (plainData == null || plainData.length < 2) {
return;
}
switch (plainData[1]) {
case 0xe:
switch(currentAction){
case ACTION_MOVE_BUDDY:
tmpBuddy.visibility = ICQConstants.VIS_NOT_AUTHORIZED;
//moveBuddy(tmpBuddy);
break;
case ACTION_RENAME_BUDDY:
tmpBuddy.visibility = ICQConstants.VIS_NOT_AUTHORIZED;
modifyBuddy(tmpBuddy);
break;
case ACTION_ADD_BUDDY:
tmpBuddy.visibility = ICQConstants.VIS_NOT_AUTHORIZED;
tmpGroup.buddies.add(tmpBuddy.itemId);
addBuddyToContactList(tmpBuddy, tmpGroup, true);
break;
}
case 0x0:
switch (currentAction) {
case ACTION_RENAME_GROUP:
service.getServiceResponse().respond(ICQServiceResponse.RES_GROUPMODIFIED, tmpGroup);
tmpGroup = null;
currentAction = ACTION_NONE;
break;
case ACTION_MOVE_BUDDY:
case ACTION_RENAME_BUDDY:
service.getServiceResponse().respond(ICQServiceResponse.RES_BUDDYMODIFIED, tmpBuddy);
tmpBuddy = null;
currentAction = ACTION_NONE;
break;
case ACTION_DELETE_BUDDY:
service.getServiceResponse().respond(ICQServiceResponse.RES_BUDDYDELETED, tmpBuddy);
tmpBuddy = null;
currentAction = ACTION_NONE;
break;
case ACTION_ADD_BUDDY:
service.getServiceResponse().respond(ICQServiceResponse.RES_BUDDYADDED, tmpBuddy);
tmpBuddy = null;
currentAction = ACTION_NONE;
break;
case ACTION_ADD_GROUP:
service.getBuddyList().buddyGroupList.add(tmpGroup);
service.getServiceResponse().respond(ICQServiceResponse.RES_GROUPADDED, tmpGroup);
tmpGroup = null;
currentAction = ACTION_NONE;
break;
case ACTION_DELETE_GROUP:
service.getServiceResponse().respond(ICQServiceResponse.RES_GROUPDELETED, tmpGroup);
tmpGroup = null;
currentAction = ACTION_NONE;
break;
/*case ACTION_UPLOAD_ICON:
currentAction = ACTION_NONE;
service.getBuddyIconEngine().requestIconUpload(newIcon);
newIcon = null;
break;*/
}
break;
}
// sendSSIEditEnd();
}
private Flap getSSIEditStartFlap() {
Flap flap1 = new Flap();
flap1.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac data1 = new Snac();
data1.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data1.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_CONTACTSEDITSTART;
data1.requestId = ICQConstants.SNAC_SERVERSIDEINFO_CONTACTSEDITSTART;
flap1.data = data1;
return flap1;
}
private Flap getSSIEditEndFlap() {
Flap flap3 = new Flap();
flap3.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac data3 = new Snac();
data3.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data3.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_CONTACTSEDITEND;
data3.requestId = ICQConstants.SNAC_SERVERSIDEINFO_CONTACTSEDITEND;
flap3.data = data3;
return flap3;
}
private Flap getAddBuddyFlap(ICQBuddy buddy, ICQBuddyGroup group, boolean authorizationRequired, boolean fixPermissions) {
Flap flap2 = new Flap();
flap2.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac data2 = new Snac();
data2.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data2.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMADD;
data2.requestId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMADD;
byte[] uinBytes;
try {
uinBytes = buddy.uin.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
uinBytes = buddy.uin.getBytes();
}
byte[] header = new byte[10 + uinBytes.length];
int pos = 0;
System.arraycopy(ProtocolUtils.short2ByteBE((short) uinBytes.length), 0, header, pos, 2);
pos += 2;
System.arraycopy(uinBytes, 0, header, pos, uinBytes.length);
pos += uinBytes.length;
int groupId;
if (!fixPermissions){
if (group!=null){
groupId = group.groupId;
} else {
groupId = buddy.groupId;
}
} else {
groupId = 0;
}
System.arraycopy(ProtocolUtils.short2ByteBE((short) groupId), 0, header, pos, 2);
pos += 2;
int itemId;
if (!fixPermissions){
itemId = buddy.itemId;
} else {
switch (buddy.visibility) {
case ICQConstants.VIS_DENIED:
do {
itemId = (short) new Random().nextInt(0x7fff);
} while (service.getBuddyList().denyList.containsValue(itemId));
service.getBuddyList().denyList.put(buddy.uin, (short) itemId);
break;
case ICQConstants.VIS_PERMITTED:
do {
itemId = (short) new Random().nextInt(0x7fff);
} while (service.getBuddyList().permitList.containsValue(itemId));
service.getBuddyList().permitList.put(buddy.uin, (short) itemId);
break;
default:
return null;
}
}
System.arraycopy(ProtocolUtils.short2ByteBE((short) itemId), 0, header, pos, 2);
pos += 2;
int itemType;
if (!fixPermissions) {
itemType = 0;
} else {
switch (buddy.visibility) {
case ICQConstants.VIS_DENIED:
itemType = 3;
break;
case ICQConstants.VIS_PERMITTED:
itemType = 2;
break;
default:
return null;
}
}
System.arraycopy(ProtocolUtils.short2ByteBE((short) itemType), 0, header, pos, 2);
pos += 2;
String screenname;
if (buddy.screenName != null) {
screenname = buddy.screenName;
} else {
screenname = buddy.uin;
}
TLV tlv = new TLV();
tlv.type = 0x131;
byte[] screennameBytes;
try {
screennameBytes = screenname.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
screennameBytes = screenname.getBytes();
}
tlv.value = screennameBytes;
TLV email = new TLV();
email.type = 0x137;
TLV sms = new TLV();
sms.type = 0x13a;
TLV comment = new TLV();
comment.type = 0x13c;
if (authorizationRequired) {
TLV authTlv = new TLV();
authTlv.type = 0x66;
data2.data = new TLV[] { tlv, sms, email, comment, authTlv };
group.buddies.add(buddy.itemId);
tmpGroup = group;
} else {
data2.data = new TLV[] { tlv, sms, email, comment };
}
System.arraycopy(ProtocolUtils.short2ByteBE((short) (16 + screennameBytes.length + (authorizationRequired ? 4 : 0))), 0, header, pos, 2);
pos += 2;
data2.plainData = header;
flap2.data = data2;
return flap2;
}
private Flap getAddBuddiesFlap(List<ICQBuddy> buddies, ICQBuddyGroup group) {
Flap flap2 = new Flap();
flap2.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac data2 = new Snac();
data2.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data2.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMADD;
data2.requestId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMADD;
List<byte[]> bytes = new ArrayList<byte[]>(buddies.size());
int bytesCount = 0;
for (ICQBuddy buddy : buddies) {
byte[] uinBytes;
try {
uinBytes = buddy.uin.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
uinBytes = buddy.uin.getBytes();
}
byte[] header = new byte[10 + uinBytes.length];
int pos = 0;
System.arraycopy(ProtocolUtils.short2ByteBE((short) uinBytes.length), 0, header, pos, 2);
pos += 2;
System.arraycopy(uinBytes, 0, header, pos, uinBytes.length);
pos += uinBytes.length;
System.arraycopy(ProtocolUtils.short2ByteBE((short) group.groupId), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) buddy.itemId), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0), 0, header, pos, 2);
pos += 2;
String screenname;
if (buddy.screenName != null) {
screenname = buddy.screenName;
} else {
screenname = buddy.uin;
}
TLV tlv = new TLV();
tlv.type = 0x131;
byte[] screennameBytes;
try {
screennameBytes = screenname.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
screennameBytes = screenname.getBytes();
}
tlv.value = screennameBytes;
TLV email = new TLV();
email.type = 0x137;
TLV sms = new TLV();
sms.type = 0x13a;
TLV comment = new TLV();
comment.type = 0x13c;
if (buddy.visibility == ICQConstants.VIS_NOT_AUTHORIZED) {
TLV authTlv = new TLV();
authTlv.type = 0x66;
data2.data = new TLV[] { tlv, sms, email, comment, authTlv };
group.buddies.add(buddy.itemId);
tmpGroup = group;
} else {
data2.data = new TLV[] { tlv, sms, email, comment };
}
System.arraycopy(ProtocolUtils.short2ByteBE((short) (16 + screennameBytes.length + ((buddy.visibility == ICQConstants.VIS_NOT_AUTHORIZED) ? 4 : 0))), 0, header, pos, 2);
pos += 2;
bytes.add(header);
bytesCount += header.length;
}
byte[] main = new byte[bytesCount];
bytesCount = 0;
for (byte[] part : bytes) {
System.arraycopy(part, 0, main, bytesCount, part.length);
bytesCount += part.length;
}
data2.plainData = main;
flap2.data = data2;
return flap2;
}
private Flap getModifyGroupFlap(ICQBuddyGroup group) {
Flap flap1 = new Flap();
flap1.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac snac1 = new Snac();
snac1.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
snac1.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_GROUPHEADERUPD;
snac1.requestId = ICQConstants.SNAC_SERVERSIDEINFO_GROUPHEADERUPD;
byte[] groupNameBytes;
try {
groupNameBytes = group.name.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
groupNameBytes = group.name.getBytes();
}
TLV groupContentsTlv = new TLV();
groupContentsTlv.type = 0xc8;
byte[] contents = new byte[2 * group.buddies.size()];
for (int i = 0; i < group.buddies.size(); i++) {
System.arraycopy(ProtocolUtils.short2ByteBE(group.buddies.get(i).shortValue()), 0, contents, 2 * i, 2);
}
groupContentsTlv.value = contents;
byte[] tlvBytes = service.getDataParser().tlvs2Bytes(new TLV[] { groupContentsTlv });
byte[] result = new byte[10 + groupNameBytes.length + tlvBytes.length];
int pos = 0;
System.arraycopy(ProtocolUtils.short2ByteBE((short) groupNameBytes.length), 0, result, pos, 2);
pos += 2;
System.arraycopy(groupNameBytes, 0, result, pos, groupNameBytes.length);
pos += groupNameBytes.length;
System.arraycopy(ProtocolUtils.short2ByteBE((short) group.groupId), 0, result, pos, 2);
pos += 2;
System.arraycopy(new byte[] { 0, 0 }, 0, result, pos, 2);
pos += 2;
System.arraycopy(new byte[] { 0, 1 }, 0, result, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) tlvBytes.length), 0, result, pos, 2);
pos += 2;
System.arraycopy(tlvBytes, 0, result, pos, tlvBytes.length);
// pos+=tlvBytes.length;
snac1.plainData = result;
flap1.data = snac1;
return flap1;
}
public void addBuddyToContactList(ICQBuddy buddy, ICQBuddyGroup group, boolean authorizationRequired) {
this.tmpGroup = group;
this.tmpBuddy = buddy;
currentAction = ACTION_ADD_BUDDY;
service.getRunnableService().sendMultipleToSocket(new Flap[] { getSSIEditStartFlap(), getAddBuddyFlap(buddy, group, authorizationRequired, false), getModifyGroupFlap(group), getSSIEditEndFlap() });
}
public void sendAuthorizationRequest(String uin, String reason) {
service.getRunnableService().sendMultipleToSocket(new Flap[] { getGrantFutureAuthorizationFlap(uin), getAuthRequestFlap(uin, reason) });
}
public void sendAuthorizationReply(String buddyUid, boolean authorized) {
service.getRunnableService().sendMultipleToSocket(new Flap[] { getGrantFutureAuthorizationFlap(buddyUid), getAuthReplyFlap(buddyUid, authorized) });
}
private Flap getGrantFutureAuthorizationFlap(String buddyUid) {
Flap flap1 = new Flap();
flap1.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac snac1 = new Snac();
snac1.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
snac1.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_CLIENTAUTHGRANT;
snac1.requestId = ICQConstants.SNAC_SERVERSIDEINFO_CLIENTAUTHGRANT;
byte[] uinBytes;
try {
uinBytes = buddyUid.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
uinBytes = buddyUid.getBytes();
}
byte[] data = new byte[5 + uinBytes.length];
data[0] = (byte) uinBytes.length;
System.arraycopy(uinBytes, 0, data, 1, uinBytes.length);
System.arraycopy(new byte[] { 0, 0, 0, 0 }, 0, data, uinBytes.length + 1, 4);
snac1.plainData = data;
flap1.data = snac1;
return flap1;
}
private Flap getAuthRequestFlap(String uin, String reason) {
Flap flap1 = new Flap();
flap1.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac snac1 = new Snac();
snac1.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
snac1.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_AUTHREQSEND;
snac1.requestId = ICQConstants.SNAC_SERVERSIDEINFO_AUTHREQSEND;
byte[] uinBytes;
try {
uinBytes = uin.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
uinBytes = uin.getBytes();
}
byte[] reasonBytes;
try {
reasonBytes = reason.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
reasonBytes = reason.getBytes();
}
byte[] data = new byte[reasonBytes.length + uinBytes.length + 5];
data[0] = (byte) uinBytes.length;
System.arraycopy(uinBytes, 0, data, 1, uinBytes.length);
System.arraycopy(ProtocolUtils.short2ByteBE((short) reasonBytes.length), 0, data, 1 + uinBytes.length, 2);
System.arraycopy(reasonBytes, 0, data, uinBytes.length + 3, reasonBytes.length);
data[uinBytes.length + 3 + reasonBytes.length] = 0;
data[uinBytes.length + 4 + reasonBytes.length] = 0;
snac1.plainData = data;
flap1.data = snac1;
return flap1;
}
private Flap getAuthReplyFlap(String buddyUid, boolean granted) {
Flap flap1 = new Flap();
flap1.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac snac1 = new Snac();
snac1.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
snac1.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_AUTHRESSEND;
snac1.requestId = ICQConstants.SNAC_SERVERSIDEINFO_AUTHRESSEND;
byte[] uinBytes;
try {
uinBytes = buddyUid.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
uinBytes = buddyUid.getBytes();
}
byte[] data = new byte[uinBytes.length + 4];
data[0] = (byte) uinBytes.length;
System.arraycopy(uinBytes, 0, data, 1, uinBytes.length);
data[uinBytes.length + 1] = (byte) (granted ? 1 : 0);
System.arraycopy(new byte[] { 0, 0 }, 0, data, uinBytes.length + 2, 2);
snac1.plainData = data;
flap1.data = snac1;
return flap1;
}
public void moveBuddies(List<ICQBuddy> buddies, ICQBuddyGroup oldGroup, ICQBuddyGroup newGroup) {
service.getRunnableService().sendMultipleToSocket(new Flap[] { getSSIEditStartFlap(), getRemoveBuddiesFlap(buddies), getModifyGroupFlap(oldGroup) });
for (ICQBuddy buddy : buddies) {
buddy.groupId = newGroup.groupId;
}
service.getRunnableService().sendMultipleToSocket(new Flap[] { getAddBuddiesFlap(buddies, newGroup), getModifyGroupFlap(newGroup), getSSIEditEndFlap() });
}
public void removeBuddies(List<ICQBuddy> buddies) {
service.getRunnableService().sendMultipleToSocket(new Flap[] { getSSIEditStartFlap(), getRemoveBuddiesFlap(buddies), getSSIEditEndFlap() });
}
private Flap getRemoveBuddiesFlap(List<ICQBuddy> buddies) {
Flap flap2 = new Flap();
flap2.channel = ICQConstants.FLAP_CHANNELL_DATA;
Snac data2 = new Snac();
data2.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data2.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMREMOVE;
data2.requestId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMREMOVE;
List<byte[]> bytes = new ArrayList<byte[]>(buddies.size());
int bytesCount = 0;
for (ICQBuddy buddy : buddies) {
byte[] uinBytes;
try {
uinBytes = buddy.uin.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
uinBytes = buddy.uin.getBytes();
}
byte[] header = new byte[10 + uinBytes.length];
int pos = 0;
System.arraycopy(ProtocolUtils.short2ByteBE((short) uinBytes.length), 0, header, pos, 2);
pos += 2;
System.arraycopy(uinBytes, 0, header, pos, uinBytes.length);
pos += uinBytes.length;
System.arraycopy(ProtocolUtils.short2ByteBE((short) buddy.groupId), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) buddy.itemId), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0), 0, header, pos, 2);
pos += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0), 0, header, pos, 2);
pos += 2;
bytes.add(header);
bytesCount += header.length;
}
byte[] main = new byte[bytesCount];
bytesCount = 0;
for (byte[] part : bytes) {
System.arraycopy(part, 0, main, bytesCount, part.length);
bytesCount += part.length;
}
data2.plainData = main;
flap2.data = data2;
return flap2;
}
public void modifyMyVisibility(ICQOnlineInfo onlineInfo) {
service.getRunnableService().sendToSocket(getModifyBuddyFlap(null, onlineInfo));
}
public void modifyVisibility(ICQBuddy icqBuddy) {
service.getRunnableService().sendMultipleToSocket(new Flap[]{getDeleteBuddyFlap(icqBuddy, true), getAddBuddyFlap(icqBuddy, null, false, true)});
}
public void requestIconUpload(byte[] icon) {
newIcon = icon;
if (newIcon == null) {
service.log("Icon to upload is null!");
return;
}
Snac data1 = new Snac();
ICQIconData iconData = service.getOnlineInfo().iconData;
if (newIcon.length > 0 && (iconData == null || iconData.ssiItemId == 0)) {
service.getOnlineInfo().iconData = new ICQIconData();
service.getOnlineInfo().iconData.ssiItemId = service.generateNewItemId();
data1.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data1.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMADD;
data1.requestId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMADD;
prepareSSIIconActionData(new MD5().calculate(newIcon), (byte) 1, data1);
} else {
data1.serviceId = ICQConstants.SNAC_FAMILY_SERVERSIDEINFO;
data1.subtypeId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMREMOVE;
data1.requestId = ICQConstants.SNAC_SERVERSIDEINFO_ITEMREMOVE;
if (iconData.hash == null) {
prepareSSIIconActionData(new MD5().calculate(newIcon), (byte) 1, data1);
} else {
prepareSSIIconActionData(iconData.hash, (byte) 1, data1);
}
if (newIcon.length < 1) {
newIcon = null;
}
}
Flap flap1 = new Flap();
flap1.channel = ICQConstants.FLAP_CHANNELL_DATA;
flap1.data = data1;
service.getRunnableService().sendToSocket(flap1);
}
private void prepareSSIIconActionData(byte[] hash, byte flags, Snac container) {
byte[] tlvData = new byte[hash.length + 2];
tlvData[0] = flags;
tlvData[1] = (byte) hash.length;
System.arraycopy(hash, 0, tlvData, 2, hash.length);
TLV hashTlv = new TLV((short) 0xd5, tlvData);
TLV xz = new TLV((short) 0x131, new byte[0]);
byte[] uinBytes;
try {
uinBytes = "1".getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
service.log(e);
uinBytes = "1".getBytes();
}
byte[] data = new byte[2 + uinBytes.length + 2 + 2 + 2 + 2];
int index = 0;
System.arraycopy(ProtocolUtils.short2ByteBE((short) uinBytes.length), 0, data, index, 2);
index += 2;
System.arraycopy(uinBytes, 0, data, index, uinBytes.length);
index += uinBytes.length;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0), 0, data, index, 2);
index += 2;
System.arraycopy(ProtocolUtils.short2ByteBE(service.getOnlineInfo().iconData != null ? service.getOnlineInfo().iconData.ssiItemId : 0), 0, data, index, 2);
index += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) 0x14), 0, data, index, 2);
index += 2;
System.arraycopy(ProtocolUtils.short2ByteBE((short) (tlvData.length + 8)), 0, data, index, 2);
container.plainData = data;
container.data = new TLV[]{hashTlv, xz};
}
public void parseAuthResponse(byte[] plainData) {
if (plainData == null || plainData.length < 2) {
return;
}
int index = 0;
byte uinLength = plainData[index];
index += 1;
byte[] uinBytes = new byte[uinLength];
System.arraycopy(plainData, index, uinBytes, 0, uinLength);
String uin = new String(uinBytes);
index += uinLength;
boolean acceptedAuth = plainData[index] == 1;
index += 1;
service.log("Authorization reply from " + uin + ": " + (acceptedAuth ? "Granted" : "Declined"));
if (index < plainData.length){
short reasonLength = ProtocolUtils.bytes2ShortBE(plainData, index);
index += 2;
byte[] reasonBytes = new byte[reasonLength];
System.arraycopy(plainData, index, reasonBytes, 0, reasonLength);
String reason;
try {
reason = new String(reasonBytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
reason = new String(reasonBytes);
}
service.log("Reason: " + reason);
}
if (acceptedAuth) {
service.getBuddyList().removeFromNotAuthListByUin(uin);
}
}
}